﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;

using Matchingo.Common.Constants;

namespace Matchingo.Modules.OptionsModule.Views
{
    public partial class OptionsView : UserControl, IOptionsScreenView
    {
		#region =============== Local Members ===============

        private const string MENU_SLIDE_IN_LEFT_STORYBOARD = "SlideInLeftStoryboard";
        private const string MENU_SLIDE_OUT_LEFT_STORYBOARD = "SlideOutLeftStoryboard";

        public UIElement RootElement { get { return LayoutRoot; } }

        private OptionsScreenViewModel ViewModel { get; set; }

		#endregion

		#region =============== Constructors ===============

        public OptionsView()
        {            
            InitializeComponent();
		}

		#endregion

		#region =============== Public Methods ===============

		public void Initialize(OptionsScreenViewModel viewModel)
        {
            ViewModel = viewModel;
            DataContext = ViewModel;

			SetupBackgroundsComboBox();
			SetupCardsSetComboBox();
            UpdateControlValues();

            ViewModel.PropertyChanged += (s, e) => UpdateControlValues();
        }

        public void ShowScreen(bool skipAnimation)
        {
            PlayStoryboard(MENU_SLIDE_IN_LEFT_STORYBOARD, skipAnimation);
        }
        public void HideScreen(bool skipAnimation)
        {
            PlayStoryboard(MENU_SLIDE_OUT_LEFT_STORYBOARD, skipAnimation);
        }

        public void UpdateControlValues()
        {
			UpdateCardCountComboBox();
			UpdateVolumeSlider();
			UpdateBackgroundSetListing();
			UpdateCardSetListing();
		}

		#endregion

        #region =============== Private Methods ===============

        private void PlayStoryboard(string storyBoardName, bool skipAnimation)
        {
            Application.Current.RootVisual.Dispatcher.BeginInvoke(() =>
            {
                Storyboard sb = (Storyboard)this.Resources[storyBoardName];
                sb.Begin();
                if (skipAnimation)
                {
                    sb.SkipToFill();
                }
            });
        }

		private void SetupCardsSetComboBox()
		{
			CardSetComboBox.SelectionChanged -= CardSetComboBox_SelectionChanged; // TODO:: lots of duplicate detach/attach from eventing 

			// items combobox
			CardSetComboBox.Items.Clear();
			CardSetComboBox.Items.Add(CommonConstants.GAME_SETTINGS_IMAGESETS_RANDOM);
			foreach (string cardSetName in ViewModel.CardSetNames)
			{
				CardSetComboBox.Items.Add(cardSetName);
			}
			CardSetComboBox.SelectedIndex = 0;

			CardSetComboBox.SelectionChanged += CardSetComboBox_SelectionChanged;
		}

		private void SetupBackgroundsComboBox()
		{
			BackgroundComboBox.SelectionChanged -= BackgroundSetComboBox_SelectionChanged;

			// backgrounds combobox
			BackgroundComboBox.Items.Clear();
			BackgroundComboBox.Items.Add(CommonConstants.GAME_SETTINGS_IMAGESETS_RANDOM);
			foreach (string backgroundSetName in ViewModel.BackgroundSetNames)
			{
				BackgroundComboBox.Items.Add(backgroundSetName);
			}
			BackgroundComboBox.SelectedIndex = 0;

			BackgroundComboBox.SelectionChanged += BackgroundSetComboBox_SelectionChanged;
		}		

		private void UpdateBackgroundSetListing()
		{
			BackgroundComboBox.SelectionChanged -= BackgroundSetComboBox_SelectionChanged;

			// set the selection
			foreach (string backgroundName in BackgroundComboBox.Items)
			{
				if (backgroundName == ViewModel.SelectedBackgroundSetName)
				{
					BackgroundComboBox.SelectedItem = backgroundName;
				}
			}

			BackgroundComboBox.SelectionChanged += BackgroundSetComboBox_SelectionChanged;
		}

		private void UpdateCardSetListing()
		{
			CardSetComboBox.SelectionChanged -= CardSetComboBox_SelectionChanged;

			// set the selection
			foreach (string cardsetName in CardSetComboBox.Items)
			{
				if (cardsetName == ViewModel.SelectedCardSetName)
				{
					CardSetComboBox.SelectedItem = cardsetName;
				}
			}

			CardSetComboBox.SelectionChanged += CardSetComboBox_SelectionChanged;
		}

		private void UpdateCardCountComboBox()
		{
			CardCountComboBox.SelectionChanged -= CardCountComboBox_SelectionChanged;

			// set the card count selection
			foreach (ComboBoxItem cbi in CardCountComboBox.Items)
			{
				if (cbi.Content.ToString() == ViewModel.CardCount.ToString())
				{
					CardCountComboBox.SelectedItem = cbi;
				}
			}

			CardCountComboBox.SelectionChanged += CardCountComboBox_SelectionChanged;
		}

		private void UpdateVolumeSlider()
		{
			VolumeSlider.ValueChanged -= VolumeSlider_ValueChanged;

			// set the sound volume slider
			VolumeSlider.Value = ViewModel.SoundVolume;
			UpdateVolumeText();

			VolumeSlider.ValueChanged += VolumeSlider_ValueChanged;
		}

		private void UpdateVolumeText()
		{
			// volume is 0.00 to 1.00, display to user as 0 to 100
			VolumeValueLabel.Text = Convert.ToInt32(ViewModel.SoundVolume * 100).ToString();
		}

		#endregion

		#region =============== Event Handlers ===============


		private void CardCountComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			// this can be called during initialization, so make sure its not null
		    if (CardCountComboBox == null) 
                return;

		    ComboBoxItem cbi = (ComboBoxItem)CardCountComboBox.SelectedItem;
		    ViewModel.CardCount = int.Parse(cbi.Content.ToString());
		}

		private void VolumeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			// this can be called during initialization, so make sure its not null
		    if (VolumeSlider == null) 
                return;

		    ViewModel.SoundVolume = VolumeSlider.Value;
		    UpdateVolumeText();
		}

		private void CardSetComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			// this can be called during initialization, so make sure its not null
            if (CardSetComboBox == null)
                return;

    		ViewModel.SelectedCardSetName = CardSetComboBox.SelectedItem.ToString();
		}

		private void BackgroundSetComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			// this can be called during initialization, so make sure its not null
			if (BackgroundComboBox == null)
			    return;

			ViewModel.SelectedBackgroundSetName = BackgroundComboBox.SelectedItem.ToString();
		}

		#endregion
	}
}
